use chrono::{Datelike, NaiveDate};

pub trait DateTrait {
    fn date(&self) -> NaiveDate;
    fn ymd(&self) -> i64;
}

// 20240101
impl DateTrait for i64 {
    fn date(&self) -> NaiveDate {
        let y = self / 10000;
        let m = (self % 10000) / 100;
        let d = self % 100;
        let r = NaiveDate::from_ymd_opt(y as i32, m as u32, d as u32);
        match r {
            Some(date) => date,
            None => chrono::Local::now().naive_local().date(),
        }
    }
    fn ymd(&self) -> i64 {
        *self
    }
}

// 20240101
impl DateTrait for i32 {
    fn date(&self) -> NaiveDate {
        (*self as i64).date()
    }
    fn ymd(&self) -> i64 {
        *self as i64
    }
}

// NaiveDate
impl DateTrait for chrono::NaiveDate {
    fn date(&self) -> NaiveDate {
        *self
    }
    fn ymd(&self) -> i64 {
        let y = self.year();
        let m = self.month();
        let d = self.day();
        y as i64 * 10000 + m as i64 * 100 + d as i64
    }
}

// NaiveDateTime
impl DateTrait for chrono::NaiveDateTime {
    fn date(&self) -> NaiveDate {
        self.date()
    }
    fn ymd(&self) -> i64 {
        self.date().ymd()
    }
}
